using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.ApplicationBlocks.Data;

namespace Avanzis.QueryExecutor.SqlClient
{
    /// <summary>
    ///     Ejecuta las sentencias SQL para una base de datos SQL Server
    /// </summary>
    public class MsSqlQueryFrameworkQueryFrameworkProvider : QueryFrameworkQueryFrameworkProvider
    {
        public override DataSet ExecuteDataset(DbConnection connection, CommandType commandType, string commandText,
            params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteDataset((SqlConnection) connection, commandType, commandText, sqlParameters);
        }

        public override DbDataReader ExecuteReader(DbConnection connection, CommandType commandType, string commandText,
            bool externalConnection, params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteReader((SqlConnection) connection, commandType, commandText, sqlParameters);
        }

        public override int ExecuteNonQuery(DbConnection connection, CommandType commandType, string commandText,
            params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteNonQuery((SqlConnection) connection, commandType, commandText, sqlParameters);
        }

        public override int ExecuteNonQuery(DbTransaction transaction, CommandType commandType, string commandText,
            params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteNonQuery((SqlTransaction) transaction, commandType, commandText, sqlParameters);
        }

        public override object ExecuteScalar(DbConnection connection, CommandType commandType, string commandText,
            params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteScalar((SqlConnection) connection, commandType, commandText, sqlParameters);
        }

        public override object ExecuteScalar(DbTransaction transaction, CommandType commandType, string commandText,
            params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteScalar((SqlTransaction) transaction, commandType, commandText, sqlParameters);
        }

        public override DbConnection CreateConnection(string connectionString)
        {
            return new SqlConnection(connectionString);
        }

        public override DataSet ExecuteDataset(DbConnection connection, CommandType commandType, string commandText)
        {
            return SqlHelper.ExecuteDataset((SqlConnection) connection, commandType, commandText);
        }

        public override DbDataReader ExecuteReader(DbConnection connection, CommandType commandType, string commandText,
            bool externalConnection)
        {
            return SqlHelper.ExecuteReader((SqlConnection) connection, commandType, commandText);
        }

        public override DbDataReader ExecuteReader(DbTransaction transaction, CommandType commandType,
            string commandText, params DbParameter[] parameters)
        {
            SqlParameter[] sqlParameters = CreaterParameterArray(parameters);
            return SqlHelper.ExecuteReader((SqlTransaction) transaction, commandType, commandText, sqlParameters);
        }

        public override int ExecuteNonQuery(DbConnection connection, CommandType commandType, string commandText)
        {
            return SqlHelper.ExecuteNonQuery((SqlConnection) connection, commandType, commandText);
        }

        public override int ExecuteNonQuery(DbTransaction transaction, CommandType commandType, string commandText)
        {
            return SqlHelper.ExecuteNonQuery((SqlTransaction) transaction, commandType, commandText);
        }

        public override object ExecuteScalar(DbConnection connection, CommandType commandType, string commandText)
        {
            return SqlHelper.ExecuteScalar((SqlConnection) connection, commandType, commandText);
        }

        public override object ExecuteScalar(DbTransaction transaction, CommandType commandType, string commandText)
        {
            return SqlHelper.ExecuteScalar((SqlTransaction) transaction, commandType, commandText);
        }

        protected virtual SqlParameter[] CreaterParameterArray(params DbParameter[] parameters)
        {
            if (parameters == null || parameters.Length == 0)
                return null;

            var returnedParameters = new List<SqlParameter>();

            if (parameters.Length > 0)
            {
                foreach (var queryParameter in parameters)
                {
                    returnedParameters.Add((SqlParameter) queryParameter);
                }
            }
            return returnedParameters.ToArray();
        }

        public override DbCommand CreateCommand(string commandText, DbConnection connection)
        {
            return new SqlCommand(commandText, (SqlConnection) connection);
        }

        public override DbDataAdapter CreateDataAdapter(DbCommand command)
        {
            return new SqlDataAdapter((SqlCommand) command);
        }

        public override DbDataAdapter CreateDataAdapter(string commandText, DbConnection connection)
        {
            return new SqlDataAdapter(commandText, (SqlConnection) connection);
        }

        public override DbParameter CreateParameter(string parameterName, object parameterValue)
        {
            return new SqlParameter(parameterName, parameterValue);
        }

        public override object ProcessDatabaseValue(object value)
        {
            return value;
        }
    }
}

